package com.honey.mamabike.security;

import java.io.ByteArrayOutputStream;
import java.io.IOException;

/**
 * Created by setsun on 2017/10/10.
 */
public class Base64Util {

    private static final char[] legalChars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
            .toCharArray();
    /**
    *@Author benson {www.honey520.com}
    *@Date 2017/10/10 14:54
    *@Description 加密算法
    */
    public static String encode(byte[] data){
        byte start = 0;
        int len = data.length;
        StringBuffer buffer = new StringBuffer(data.length*3/2);
        int end  = len - 3;
        int i = start;
        int n = 0;

        int d;
        while(i<=end){
            d = (data[i] & 255) << 16 | (data[i+1] & 255) << 8 | data[i+2] & 255;
            buffer.append(legalChars[d >> 18 & 63]);
            buffer.append(legalChars[d >> 12 & 63]);
            buffer.append(legalChars[d >> 6 & 63]);
            buffer.append(legalChars[d & 63]);
            i += 3;
            if (n++ >= 14){
                n = 0;
                buffer.append(" ");
            }
        }

        if (i == start + len -2){
            d = (data[i] & 255 ) << 16 | (data[i+1] & 255) << 8;
            buffer.append(legalChars[d >> 18 & 63]);
            buffer.append(legalChars[d >> 12 & 63]);
            buffer.append(legalChars[d >> 6 & 63]);
            buffer.append(legalChars[d & 63]);
            buffer.append("=");
        }else if (i == start + len - 1){
            d = (data[i] & 255 ) << 16;
            buffer.append(legalChars[d >> 18 & 63]);
            buffer.append(legalChars[d >> 12 & 63]);
            buffer.append("==");
        }

        return  buffer.toString();
    }

    private static int decode(char c){
        if (c >= 65 && c <= 90){
            return c - 65;
        }else if (c >= 97 && c <= 122){
            return c - 97 + 26;
        }else if (c >= 48 && c <= 57){
            return c - 48 + 26 + 26;
        }else{
            switch (c){
                case '+':
                    return 62;
                case '/':
                    return 63;
                case '=':
                    return 0;
                default:
                    throw new RuntimeException("unexpected code:"+c);
            }
        }
    }

    /**
    *@Author benson {www.honey520.com}
    *@Date 2017/10/10 14:55
    *@Description 解密算法
    */
     public static byte[] decode(String s){
         ByteArrayOutputStream bos = new ByteArrayOutputStream();
         try{
             decode(s,bos);
         }catch (IOException var5){
             throw new RuntimeException();
         }
         byte[] decodedBytes = bos.toByteArray();
         try{
             bos.close();
             bos = null;
         } catch (IOException var4) {
             System.err.println("Error while decoding BASE64:"+ var4.toString());
         }

        return decodedBytes;
     }

    private static void decode(String s, ByteArrayOutputStream os)throws IOException {
        int i = 0;
        int len = s.length();
        while(true){
            while(i < len && s.charAt(i) <= 32){
                ++i;
            }
            if (i == len){
                break;
            }

            int tri = (decode(s.charAt(i)) << 18) + (decode(s.charAt(i + 1)) << 12) + (decode(s.charAt(i + 2)) << 6) + decode(s.charAt(i + 3));
            os.write(tri >> 16 & 255);
            if (s.charAt(i + 2) == 61){
                break;
            }
            os.write(tri >> 8 & 255);
            if (s.charAt(i + 3) == 61){
                break;
            }
            os.write(tri & 255);
            i += 4;

        }
    }


}
